package ligne2vie.topos.server.bo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.Inheritance;
import javax.jdo.annotations.InheritanceStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.google.appengine.api.datastore.Key;
import com.google.gwt.maps.client.base.HasLatLng;
import com.google.gwt.maps.client.base.LatLng;

/**
 * The class {@link MapPoint} is a business object modeling a point on a map, having default and required attributes. It
 * has been designed to be inherited from other point types.
 * 
 * @author thuguerre
 * @since 1.0.0
 */
@PersistenceCapable(detachable = "true")
@Inheritance(strategy = InheritanceStrategy.SUBCLASS_TABLE)
public abstract class MapPoint implements Serializable {

	/**
	 * Default serial UID.
	 */
	private static final long serialVersionUID = -6761276368781012345L;

	/**
	 * Point's identifier;
	 */
	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	protected Key id;

	/**
	 * Point's name.
	 */
	@Persistent
	protected String name;

	/**
	 * Point's latitude.
	 */
	@Persistent
	protected double latitude;

	/**
	 * Point's longitude.
	 */
	@Persistent
	protected double longitude;

	/**
	 * Point's altitude, in meters.
	 */
	@Persistent
	protected int altitude;

	/**
	 * Point's description. Please refer to implementation to have mode information about description format (HTML,
	 * simple text, ...).
	 */
	@Persistent
	protected String description;

	/**
	 * Point's state in application.
	 */
	@Persistent
	protected EntityState state;

	/**
	 * Point's histories.
	 */
	@Persistent(defaultFetchGroup = "true")
	protected List<ActionHistory> histories;

	public Key getId() {
		return id;
	}

	public void setId(Key id) {
		this.id = id;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getLatitude() {
		return latitude;
	}

	public void setLatitude(double latitude) {
		this.latitude = latitude;
	}

	public double getLongitude() {
		return longitude;
	}

	public void setLongitude(double longitude) {
		this.longitude = longitude;
	}

	public int getAltitude() {
		return altitude;
	}

	public void setAltitude(int altitude) {
		this.altitude = altitude;
	}

	public EntityState getState() {
		return state;
	}

	public void setState(EntityState state) {
		this.state = state;
	}

	public List<ActionHistory> getHistories() {
		return histories;
	}

	public void setHistories(List<ActionHistory> histories) {
		this.histories = histories;
	}

	/**
	 * The method {@link #add(ActionHistory)} allows adding safely an action history to the list of existing actions.
	 * 
	 * @param history
	 *            History to add on this object.
	 */
	public void add(ActionHistory history) {

		if (history != null) {

			if (histories == null) {
				histories = new ArrayList<ActionHistory>();
			}

			histories.add(history);
		}
	}

	/**
	 * Returns this point's position on a map, by instantiating a {@link HasLatLng} object, using owned latitude and
	 * longitude.
	 * 
	 * @return Position on a map.
	 */
	public HasLatLng getPosition() {
		return new LatLng(latitude, longitude);
	}
}
